import { IStream, ITicketInfo, LoginResponseProps, ISessionEventKey, IMediaDevices, AnswerProps } from './interface';
import {
	checkInErrorResponse,
	checkOutErrorResponse,
	readyErrorResponse,
	unReadyErrorResponse,
	answerErrorResponse,
	loginErrorResponse,
	requestUpgradeErrorResponse,
	acceptUpgradeErrorResponse,
	rejectUpgradeErrorResponse,
	cancelUpgradeErrorResponse,
	afterWorkEndErrorResponse
} from './errorResponse';
import AgentService from '@/modules/Agent';
import type { IVCSProps } from '../ivcs';

declare const ivcs: IVCSProps;

// 获取实时token
export const getNewToken = ()=>{
    return ivcs.agent.accessToken;
}

//初始化登录
export const initWithEncrypt = (url: string, username: string, password: string, org: string | number, defaultMediaOptions: any): Promise<LoginResponseProps> => {
	return new Promise((resolve, reject) => {
        const { configure } = AgentService;

        ivcs.agent.setcompressedPublicKey(configure.getPublicKey());
		ivcs.agent.initWithEncrypt(
			url,
			username,
			password,
			String(org),
			'', // Changed from undefined to empty string
			defaultMediaOptions,
			(resp: any) => {
				resolve(resp);
			},
			(error: any) => {
				loginErrorResponse(error);
				reject(error);
			}
		);
	});
};

/** 坐席登录系统 */
export const AgentLoginSystem = (): Promise<ITicketInfo> => {
	return new Promise((resolve, reject) => {
		ivcs.agent.login(
			(resp: any) => {
				resolve(resp);
			},
			(error: any) => {
				reject(error);
			}
		);
	});
};

/** 初始化 ams 用于 sso 登录 */
export const initWithLoginData = (backendUrl: string, data: any, mediaOptions: any) => {
	return new Promise((resolve, reject) => {
		ivcs.agent.initWithLoginData(
			backendUrl,
			data,
			mediaOptions,
			(resp: any) => {
				resolve(resp);
			},
			(error: any) => {
				reject(error);
			}
		);
	});
};
/** 获取排队数 */
export const getQueueInfo = (updateProgress: (progress: { total: number; groups: { groupName: string; groupId: number; waitingNum: number }[] }) => void, clearTimer: () => void) => {
	let response = { total: 0, groups: [] };
	ivcs.agent.getQueueInfo(
		(resp: any) => {
			// console.log('get queue info success', resp);
			response.groups = resp.map((item: any) => {
				response.total += item.waitingNum;
				return {
					groupName: item.groupName,
					groupId: item.groupId,
					waitingNum: item.waitingNum
				};
			});
			updateProgress(response);
		},
		(error: any) => {
			console.log('get queue info error', error);
			clearTimer && clearTimer();
		}
	);
};

/** 坐席签入分组 */
export const checkIn = (groups: number[]): Promise<{ code: number; message: string; data: any }> => {
	return new Promise((resolve, reject) => {
		ivcs.agent.checkIn(
			{ groups },
			(resp: any) => {
				resolve({ code: 200, message: 'success', data: resp });
			},
			(error: any) => {
				console.log('checkin error', error);
				checkInErrorResponse(error.code);
				reject(error);
			}
		);
	});
};

/** 坐席签出分组 */
export const checkOut = (groups: number[]): Promise<{ code: number; message: string; data: any }> => {
	return new Promise((resolve, reject) => {
		ivcs.agent.checkOut(
			{ groups },
			(resp: any) => {
				resolve({ code: 200, message: 'success', data: resp });
			},
			(error: any) => {
				console.log('checkout error', error);
				checkOutErrorResponse(error.code);
				reject(error);
			}
		);
	});
};

/** 坐席就绪 */
export const ready = (): Promise<{ code: number; message: string; data: any }> => {
	return new Promise((resolve, reject) => {
		ivcs.agent.ready(
			(resp: any) => {
				resolve({ code: 200, message: 'ready success', data: resp });
			},
			(error: any) => {
				console.log('ready error', error);
				readyErrorResponse(error.code);
				reject(error);
			}
		);
	});
};

/** 坐席取消就绪 */
export const unReady = (): Promise<{ code: number; message: string; data: any }> => {
	return new Promise((resolve, reject) => {
		ivcs.agent.unReady(
			(resp: any) => {
				console.log('unReady success', resp);
				resolve({ code: 200, message: 'unReady success', data: resp });
			},
			(error: any) => {
				console.log('unReady error', error);
				unReadyErrorResponse(error.code);
				reject(error);
			}
		);
	});
};

/** 坐席退出系统 */
export const logout = () => {
	return new Promise((resolve, reject) => {
		ivcs.agent.logout(
			(resp: any) => {
				resolve({ code: 200, message: 'logout success', data: resp });
			},
			(error: any) => {
				reject(error);
			}
		);
	});
};

/** 坐席关闭页面 */
export const closePage = () => {
	ivcs.agent.userPageClose((ack: any) => {
		console.log(ack, 'userPageClose');
	});
};

/** 坐席离开 */
export const offline = () => {
	// ivcs.agent.offline();
};

/** 预约小休 */
export const appoint = (data: { reason: string }): Promise<{ code: number; message: string; data: any }> => {
	return new Promise((resolve, reject) => {
		ivcs.agent.appoint(
			data,
			(resp: any) => {
				console.log('appoint success', resp);
				resolve({ code: 200, message: 'appoint success', data: resp });
				// Message.normal(t('break-book-success'));
			},
			(error: any) => {
				console.log('appoint error', error);
				// Message.warning(t('break-book-failed'));
				reject(error);
			}
		);
	});
};

/** 取消所有的invite（取消转接和三方） */
export const cancelInvitations = () => {
	return new Promise((resolve, reject) => {
		ivcs.agent.cancelInvitations(
			(resp: any) => {
				resolve({ code: 200, message: 'cancel invitations success', data: resp });
			},
			(error: any) => {
				reject(error);
			}
		);
	});
};

/** 坐席接听会话 */
export const answer = (agentName: string, receiveMediaType: string, customizedMediaStream: any, mediaDevices: IMediaDevices): Promise<any> => {
	let agentLabel = 'agent' + agentName + '-' + Math.round(Math.random() * (1 - 10000) + 10000);
	return new Promise((resolve, reject) => {
		ivcs.agent.answer(
			agentLabel,
			receiveMediaType,
			customizedMediaStream,
			mediaDevices,
			(resp: any) => {
				resolve({ code: 200, message: 'answer success', data: resp });
			},
			(error: any) => {
				answerErrorResponse(error.code);
				reject(error);
			}
		);
	});
};

/** 坐席挂断会话 */
export const hangup = (reason: { code?: number; reason?: string }): Promise<{ code: number; message: string; data: any }> => {
	return new Promise((resolve, reject) => {
		ivcs.agent.hangup(
			reason,
			(resp: any) => {
				resolve({ code: 200, message: 'hangup success', data: resp });
			},
			(error: any) => {
				reject(error);
			}
		);
	});
};
/** 坐席拒绝会话 */
export const rejectSession = (): Promise<{ code: number; message: string; data: any }> => {
	console.warn('rejectSession');
	return new Promise((resolve, reject) => {
		ivcs.agent.reject(
			(resp: any) => {
				resolve({ code: 200, message: 'reject session success', data: resp });
			},
			(error: any) => {
				reject(error);
			}
		);
	});
};

/** 切换视频流 */
export const switchCameraWithStream = (stream: string) => {
	return new Promise((resolve, reject) => {
		ivcs.agent.switchCameraWithStream(
			stream,
			(resp: any) => {
				console.log('switch camera success', resp, stream);
				resolve({ code: 200, status: 'success', message: 'switch camera success', data: resp });
			},
			(error: any) => {
				console.log('switch camera error', error);
				reject({ code: 400, status: 'error', message: 'switch camera failed', data: error });
			},
			(onEnded: any) => {
				console.log('switch camera onEnded', onEnded);
				reject({ code: 400, status: 'error', message: 'switch camera failed', data: onEnded });
			}
		);
	});
};

/**渲染视频流 */
export const renderStream = (streamLabel: string, videoId: string, callBack?: (onEnded: any) => void): Promise<{ code: number; status: string; message: any; data: any }> => {
	return new Promise((resolve, reject) => {
		ivcs.agent.renderStream(
			streamLabel,
			videoId,
			(resp: any) => {
				resolve({ code: 200, status: 'success', message: 'render success', data: resp });
			},
			(error: any) => {
				reject({ code: 400, status: 'error', message: 'render error', data: error });
			},
			(onPlayError: any) => {
				reject({ code: 405, status: 'onPlayError', message: 'onPlayError error', data: onPlayError });
			},
			(onEnded: any) => {
				callBack && callBack(onEnded);
				reject({ code: 406, status: 'onEnded', message: 'onEnded', data: onEnded });
			},
            undefined
		);
	});
};

type ProgressType = 'idle' | 'permission' | 'publish' | 'published';

/**
 * 发送开启音视频的进度自定义消息
 * @ignore
 * @param {string} label 视频标签的标识，可根据这个标识处理业务UI的布局
 * @param {string} role 'customer' | 'agent'
 * @param {string} status 'permission' | 'publish'
 */
export const sendStartVideoProgressMessage = (label: string, clientId: string, status: ProgressType) => {
	const progressData = {
		label,
		clientId,
		role: 'agent',
		isRobotStream: false,
		status: status,
		businessType: 'notice_media_progress'
	};
	return new Promise((resolve, reject) => {
		ivcs.agent.sendCustomMessage(
			progressData,
			'others',
			(success: any) => {
				resolve(success);
			},
			(error: any) => {
				reject(error);
			}
		);
	});
};

/** 以下事件监听开始 */

/** 系统错误 */
export const systemErrorEvent = (callback: (ack: any) => void) => ivcs.agent.addEventListener('systemError', (ack: any) => callback(ack));

//监听流加入
export const onStreamAdd = (callback: (stream: IStream) => void) => ivcs.agent.addEventListener('onStreamAdd', (stream: IStream) => callback(stream));

//监听流退出
export const onStreamEnd = (callback: (stream: IStream) => void) => ivcs.agent.addEventListener('onStreamEnd', (stream: IStream) => callback(stream));

//监听ccs结束会话
export const onCcsDrop = (callback: (ack: any) => void) => ivcs.agent.onSessionDrop((ack: any) => callback(ack));

//cssError
export const ccsError = (callback: (ack: any) => void) => ivcs.agent.addEventListener('ccsError', (ack: any) => callback(ack));

//监听访客加入会话
export const onCustomerJoinSession = (callback: (ack: any) => void) => ivcs.agent.addEventListener('onCustomerJoinSession', (ack: any) => callback(ack));

//监听访客离开会话
export const onCustomerQuitSession = (callback: (ack: any) => void) => ivcs.agent.addEventListener('onCustomerQuitSession', (ack: any) => callback(ack));

//监听坐席离开会话
export const onAgentQuitSession = (callback: (ack: any) => void) => ivcs.agent.addEventListener('onAgentQuitSession', (ack: any) => callback(ack));

//监听坐席加入会话
export const onAgentJoinSession = (callback: (ack: any) => void) => ivcs.agent.addEventListener('onAgentJoinSession', (ack: any) => callback(ack));

export const onCcsResumeSuccess = (callback: (ack: string) => void) => ivcs.agent.onCcsResumeSuccess((ack: any) => callback(ack));

/**
 * 监听坐席和坐席管理服务端<ams>的链接的状态变化
 * @param {function} ack 返回{enum:['connected','reconnect_failed','reconnecting']}
 * @example
 * ivcs.agent.onConnectStatus(status => {
        //开发者的业务处理示例
        'connected':'链接成功/重连成功',//第一次触发表示和ams建立链接,后面触发表示重连成功
        'reconnect_failed':'重连失败',//无法接听，就绪，签入等任何功能,需要重新初始化
        'reconnecting':'正在重连中...'//正在重连中，无法执行任何操作
        'offline':'断网',
        'online':'网络恢复链接'
    });
*/
export const onAmsConnectStatus = (callback: (ack: string) => void) => {
    ivcs.agent.onConnectStatus((ack: any) => callback(ack));
    ivcs.agent.onAmsResumeError((ack: any) =>{
        console.log('onAmsResumeError',ack);
        callback('resume_error');
    });
};

/**
 * 监听session中其他用户ccs重连中,用于检测对方网络是否断开在重连中
 * @param {function} ack
 * @returns null
 */
export const onOtherReconnecting = (callBack: (ack: any) => void) => ivcs.agent.onOtherReconnecting((ack: any) => callBack(ack));

/**
 * 监听session中其他用户ccs重连成功,用于检测对方网络是否重连成功
 * @param {function} ack
 * @returns null
 */
export const onOtherResumeConnect = (callBack: (ack: any) => void) => ivcs.agent.onOtherResumeConnect((ack: any) => callBack(ack));

/**
 * 监听坐席和Ccs会话状态变化
 * @param {function} ack 返回{enum:['connected','reconnect_failed','reconnecting']}
 * @example
 */
export const onSessionConnectStatus = (callBack: (ack: any) => void) => ivcs.agent.onSessionConnectStatus((ack: any) => callBack(ack));

/**
 * 监听访客端本地推送画面的媒体连接状态。
 * @param {function} ack {streamLabel:string(本地推流标签),userInfo:object(该画面包含的client信息),publishStatus:{status:string('failed'|'connecting'|'connected'|'disconnected'|'quality-report'),data:object(网络状况信息)}}
 * @example
 * ivcs.agent.onPublishMediaStatus((info)=>{});
 */
export const onPublishMediaStatus = (callBack: (ack: any) => void) => ivcs.agent.onPublishMediaStatus((ack: any) => callBack(ack));

/**
 * 监听渲染的远端画面的媒体连接状态。
 * @param {function} ack {streamLabel:string(渲染的流标签),userInfo:object(该画面包含的client信息),renderStatus:{status:string('failed'|'connecting'|'connected'|'disconnected'|'quality-report'),data:object(网络状况信息)}}
 * @example
 * ivcs.agent.onRenderMediaStatus((info)=>{});
 */
export const onRenderMediaStatus = (callBack: (ack: any) => void) => ivcs.agent.onRenderMediaStatus((resp: any) => callBack(resp));

//连接异常，被系统强制结束或者其他网络原因，触发后坐席端无法正常处理会话，需要重新初始化
export const onDrop = (callback: (ack: any) => void) => ivcs.agent.onDrop((ack: any) => callback(ack));

/** 取消坐席振铃 */
export const onCancelRing = (callback: (ack: any) => void) => ivcs.agent.onCancelRing((ack: any) => callback(ack));

/** 坐席振铃 */
export const onRing = (callback: (ack: any) => void) => ivcs.agent.onRing((ack: any) => callback(ack));

/** 监听坐席小休状态 */
export const onResetStatus = (callback: (ack: any) => void) => ivcs.agent.onResetStatus((ack: any) => callback(ack));

/** 坐席邀请进度监听 */
export const onInvitationProgress = (callBack: (ack: any) => void) => ivcs.agent.onInvitationProgress((ack: any) => callBack(ack));

/** 坐席更新变量监听 */
export const onVariableChange = (callBack: (ack: any) => void) => ivcs.agent.onVariableChange((ack: any) => callBack(ack));

/** 收到资源文件信息（图片，文档等） */
export const onResourceMessage = (callback: (ack: any) => void) => ivcs.agent.onResourceMessage((ack: any) => callback(ack));

/** 接收自定义消息 */
export const onCustomizeMessage = (callback: (ack: any) => void) => ivcs.agent.onCustomMessage((ack: any) => callback(ack));

// 接受文本消息
export const onTextMessage = (callback: (message: any) => void) => ivcs.agent.onTextMessage((ack: any) => callback(ack));

/** 移除事件监听 */
export const removeSessionEvent = (key: ISessionEventKey, fn: any) => ivcs.agent.removeEventListener(key, fn);

/** 收到当前会话发生业务变化，如坐席推送了扫码，访客拒绝扫码等指令或者坐席操作 */
export const onSyncMessage = (callBack: (ack: any) => void) => ivcs.agent.onSyncMessage((ack: any) => callBack(ack));

/** 监听实时质检结果返回 如人脸比对 人证对比 敏感词 */
export const onRealTimeQuality = (callBack: (ack: any) => void) => ivcs.agent.onRealTimeQuality((ack: any) => callBack(ack));

/** 监听升降级的事件 */
export const onUpgrade = (callback: (ack: any) => void) => ivcs.agent.onUpgrade((ack: any) => callback(ack));

// 推送本地音视频画面
export const startVideo = (agentName: string, receiveMediaType: string): Promise<any> => {
	let agentLabel = 'agent' + agentName + '-' + Math.round(Math.random() * (1 - 10000) + 10000);
	return new Promise((resolve, reject) => {
		ivcs.agent.startVideo(
			agentLabel,
			receiveMediaType,
			(resp: any) => {
				console.log('start video result,', resp);
				resolve({ code: 200, message: 'start video success', data: resp });
			},
			(error: any) => {
				answerErrorResponse(error.code);
				reject(error);
			}
		);
	});
};

// 接听访客im呼叫
export const answerImCall = (): Promise<any> => {
	return new Promise((resolve, reject) => {
		ivcs.agent.answerImCall(
			(success: any) => {
				resolve(success);
			},
			(error: any) => {
				reject(error);
			}
		);
	});
};

// 请求升级
export const requestUpgrade = (media: string, toWhom: string): Promise<any> => {
	return new Promise((resolve, reject) => {
		ivcs.agent.requestUpgrade(
			media,
			toWhom,
			(success: any) => {
				resolve(success);
			},
			(error: any) => {
				requestUpgradeErrorResponse(error.code, media);
				reject(error);
			}
		);
	});
};

// 接受对方的升级请求
export const acceptUpgrade = (media: string): Promise<any> => {
	return new Promise((resolve, reject) => {
		ivcs.agent.acceptUpgrade(
			media,
			(success: any) => {
				resolve(success);
			},
			(error: any) => {
				acceptUpgradeErrorResponse(error.code, media);
				reject(error);
			}
		);
	});
};

// 拒绝接听
export const rejectUpgrade = (media: string, reason: any): Promise<any> => {
	return new Promise((resolve, reject) => {
		ivcs.agent.rejectUpgrade(
			media,
			reason,
			(success: any) => {
				resolve(success);
			},
			(error: any) => {
				rejectUpgradeErrorResponse(error.code, media);
				reject(error);
			}
		);
	});
};

// 取消请求升级
export const cancelUpgrade = (reason: string, media?: string): Promise<any> => {
	return new Promise((resolve, reject) => {
		ivcs.agent.cancelUpgrade(
			reason,
			(success: any) => {
				resolve(success);
			},
			(error: any) => {
				cancelUpgradeErrorResponse(error.code, media || '');
				reject(error);
			}
		);
	});
};

//接听音视频呼叫,成功后调用startMedia，推送本地画面
export const answerMediaCall = (mediaType: string): Promise<any> => {
	return new Promise((resolve, reject) => {
		ivcs.agent.answerMediaCall(
			mediaType,
			(success: any) => {
				resolve({ code: 200, message: 'answerMediaCall success', data: success });
			},
			(error: any) => {
				answerErrorResponse(error.code);
				reject(error);
			}
		);
	});
};

//开启本地音视频，在接听音视频呼叫后执行
export const startMedia = (agentLabel: string, mediaType: string, customizedMediaStreams: any, mediaStreamConstraints: any): Promise<any> => {
	return new Promise((resolve, reject) => {
		ivcs.agent.startMedia(
			agentLabel,
			mediaType,
			customizedMediaStreams,
			mediaStreamConstraints,
			(success: any) => {
				resolve({ code: 200, message: 'startMedia success', data: success });
			},
			(error: any) => {
				answerErrorResponse(error.code);
				reject(error);
			}
		);
	});
};

export const afterWorkEnd = (): Promise<any> => {
	return new Promise((resolve, reject) => {
		ivcs.agent.afterWorkEnd(
			(success: any) => {
				resolve({ code: 200, message: 'afterWorkEnd success', data: success });
			},
			(error: any) => {
				afterWorkEndErrorResponse(error.code);
				reject(error);
			}
		);
	});
};

//获取会话中的成员列表
export const getSessionMembers = (): Promise<any> => {
	return new Promise((resolve, reject) => {
		ivcs.agent.getSessionMembers(
			'',
			(success: any) => {
				resolve({ code: 200, message: 'getSessionMembers success', data: success });
			},
			(error: any) => {
				reject(error);
			}
		);
	});
};

//监听会话录像中断事件。
export const onSessionRecordCrash = (callback: (ack: any) => void) => ivcs.agent.onSessionRecordCrash((ack: any) => callback(ack));

// 监听系统录像变化事件
export const onSystemRecordUpdate = (callback: (ack: any) => void) => ivcs.agent.onSystemRecordUpdate((ack: any) => callback(ack));

/**
 * 坐席完成会话小结内容，通知给会话中的其他坐席
 * @param {object} data  {"bizSummaryId": 1,  //会话小结配置项ID "name": "字段名称", // 字段名称"type": "textarea", // 类型"data": {}, //选项配置内容 "value": {}, // 选项值 "isRequired": "Y"  // 是否必填  N}
 * @param {string} toWhom 发送给谁 clientId具体的用户 'customers' = 访客;'agents' = 坐席;'others' = 除了自己的所有人; 'all' = 所有人;
 * @param {function} onSuccess 发送成功  'ok'
 * @param {function} onFailure 发送失败
 */
export const syncSessionSummary = (data: any, toWhom: string): Promise<any> => {
	return new Promise((resolve, reject) => {
		ivcs.agent.syncSessionSummary(
			data,
			toWhom,
			(success: any) => {
				resolve({ code: 200, message: 'syncSessionSummary success', data: success });
			},
			(error: any) => {
				reject(error);
			}
		);
	});
};

/**
 * 监听当前会话的会话小结的内容变化，其他坐席做的会话小结变更，都会通知到当前坐席
 * @param {function} ack {"bizSummaryId": 1,  //会话小结配置项ID "name": "字段名称", // 字段名称"type": "textarea", // 类型"data": {}, //选项配置内容 "value": {}, // 选项值 "isRequired": "Y"  // 是否必填  N}
 */
export const onSyncSessionSummary = (callBack: (ack: any) => void) => ivcs.agent.onSyncSessionSummary((ack: any) => callBack(ack));
